package rh.cola.utils;

import com.unfbx.chatgpt.OpenAiClient;
import com.unfbx.chatgpt.OpenAiStreamClient;
import com.unfbx.chatgpt.interceptor.OpenAILogger;
import okhttp3.logging.HttpLoggingInterceptor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.net.InetSocketAddress;
import java.net.Proxy;
import java.util.Arrays;
import java.util.Objects;

/**
 * @Name: ChatGPTUtils
 * @Author: Cola
 * @Time: 2023/3/22 17:12
 * @Description: ChatGPTUtils
 */
@Component
public class ChatGPTUtils {
    
    private static String API_KEY;
    private static String API_HOST;

    private static String PROXY_HOST;
    private static Integer PROXY_PORT;

    private static Integer CONNECT_TIME_OUT;
    private static Integer WRITE_TIME_OUT;
    private static Integer READ_TIME_OUT;

    public ChatGPTUtils() {
    }

    /**
     * Spring 默认不允许 通过 @Value 注入 static 变量
     * 原因： Spring 依赖注入是通过 set 方法，而 set 方法是普通的对象方法 static 遍历是类的属性
     * 解决： 通过显示声明 set 方法后进行注入（注意：自动生成的 set 方法修饰符仍为 static 需去除）
     *
     * @param apiKey
     */
    @Value("${Cola.API_KEY}")
    public void setApiKey(String apiKey) {
        API_KEY = apiKey;
    }

    @Value("${Cola.API_HOST}")
    public void setApiHost(String apiHost) {
        API_HOST = apiHost;
    }

    @Value("${Cola.PROXY_HOST}")
    public void setProxyHost(String proxyHost) {
        PROXY_HOST = proxyHost;
    }

    @Value("${Cola.PROXY_PORT}")
    public void setProxyPort(Integer proxyPort) {
        PROXY_PORT = proxyPort;
    }

    @Value("${Cola.CONNECT_TIME_OUT}")
    public void setConnectTimeOut(Integer connectTimeOut) {
        CONNECT_TIME_OUT = connectTimeOut;
    }

    @Value("${Cola.WRITE_TIME_OUT}")
    public void setWriteTimeOut(Integer writeTimeOut) {
        WRITE_TIME_OUT = writeTimeOut;
    }

    @Value("${Cola.READ_TIME_OUT}")
    public void setReadTimeOut(Integer readTimeOut) {
        READ_TIME_OUT = readTimeOut;
    }

    /**
     * 通过 API_KEY 获取常规客户端
     *
     * @return OpenAiClient
     */
    public static OpenAiClient getCommonClientByApiKey() {
        /*配置代理*/
        Proxy proxy = new Proxy
                (Proxy.Type.HTTP,
                        new InetSocketAddress(PROXY_HOST, PROXY_PORT));
        /*日志设置*/
        HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor(new OpenAILogger());
        httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        /*创建客户端*/
        OpenAiClient openAiClient = OpenAiClient.builder()
                .apiHost(API_HOST)
                .apiKey(API_KEY)
                .proxy(proxy)
                .connectTimeout(CONNECT_TIME_OUT)
                .writeTimeout(WRITE_TIME_OUT)
                .readTimeout(READ_TIME_OUT)
                .interceptor(Arrays.asList(httpLoggingInterceptor))
                .build();
        return Objects.requireNonNull(openAiClient);
    }

    /**
     * 通过 API_KEY 获取流式客户端
     *
     * @return OpenAiStreamClient
     */
    public static OpenAiStreamClient getStreamClientByApiKey() {
        /*配置代理*/
        Proxy proxy = new Proxy
                (Proxy.Type.HTTP,
                        new InetSocketAddress(PROXY_HOST, PROXY_PORT));
        /*创建客户端*/
        OpenAiStreamClient openAiStreamClient = OpenAiStreamClient.builder()
                .apiHost(API_HOST)
                .apiKey(API_KEY)
                .proxy(proxy)
                .connectTimeout(CONNECT_TIME_OUT)
                .writeTimeout(WRITE_TIME_OUT)
                .readTimeout(READ_TIME_OUT)
                .build();
        return Objects.requireNonNull(openAiStreamClient);

    }
}
